home *** CD-ROM | disk | FTP | other *** search
/ Aminet 28 / Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso / Aminet / dev / misc / gms_colours.lha / Colours / colours.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-09-12  |  19.5 KB  |  653 lines

  1. /*
  2. ** Module:    Colours.
  3. ** Type:      Function based.
  4. ** Author:    Paul Manias
  5. ** Copyright: DreamWorld Productions (c) 1998.  All rights reserved.
  6. **
  7. ** --------------------------------------------------------------------------
  8. **
  9. ** TERMS AND CONDITIONS
  10. **
  11. ** This source code is made available on the condition that it is only used
  12. ** to further enhance the Games Master System.  IT IS NOT DISTRIBUTED FOR THE
  13. ** USE IN OTHER PRODUCTS.  Developers may edit and re-release this source
  14. ** code only in the form of its GMS module.  Use of this code outside of the
  15. ** module is not permitted under any circumstances.
  16. **
  17. ** This source code stays the copyright of DreamWorld Productions regardless
  18. ** of what changes or additions are made to it by 3rd parties.  A joint
  19. ** copyright can be granted if the 3rd party wishes to retain some ownership
  20. ** of said modifications.
  21. **
  22. ** In exchange for our distribution of this source code, we also ask you to
  23. ** distribute the source when releasing a modified version of this module.
  24. ** This is not compulsory if any additions are sensitive to 3rd party
  25. ** copyrights, or if it would damage any commercial product(s).
  26. **
  27. ** --------------------------------------------------------------------------
  28. **
  29. ** BUGS AND MISSING FEATURES
  30. ** -------------------------
  31. ** If you correct a bug or fill in a missing feature, the source should be
  32. ** e-mailed to pmanias@ihug.co.nz for inclusion in the next update of this
  33. ** module.
  34. **
  35. ** + To be added:
  36. **
  37. **      ConvertHSVToRGB(*HSV)
  38. **      AdjustContrast(RGB, Percent)   [Adjust RGB from -100 to 100%]
  39. **      AdjustBrightness(RGB, Percent)
  40. **      AdjustColour(RGB, Percent)
  41. **      AnalyseBitmap(Bitmap)          [Counts colours in a Bitmap]
  42. **      BlurPixel()
  43. **      XORPixel()
  44. **      NOTPixel()
  45. **      SetPenEffect(EffectNo,Setting)
  46. **        PNE_LIGHTEN, PNE_DARKEN, PNE_BLUR
  47. **
  48. ** + If you have colour functions or other special effects that are suited
  49. **   for inclusion in this module, they would be much appreciated!
  50. **
  51. ** DCC COMPILE
  52. ** -----------
  53. ** 1> dcc -c -l0 -mD -mi colours.c -o colours.o
  54. ** 1> dcc -c -l0 -mD -mi colours_data.c -o colours_data.o
  55. ** 1> dlink colours_data.o colours.o -o GMS:System/colours.mod
  56. **
  57. ** CHANGES
  58. ** -------
  59. ** 26 May Development starts today.
  60. ** 16 Aug Publicly released.
  61. */
  62.  
  63. #include <proto/dpkernel.h>
  64. #include <system/all.h>
  65.  
  66. #include "defs.h"
  67.  
  68. /***********************************************************************************/
  69.  
  70. BYTE ModAuthor[]    = "Paul Manias";
  71. BYTE ModDate[]      = "June 1998";
  72. BYTE ModCopyright[] = "DreamWorld Productions (c) 1996-1998.  All rights reserved.";
  73. BYTE ModName[]      = "Colours";
  74.  
  75. struct Function JumpTableV1[] = {
  76.   { LIBBlurArea,        "BlurArea(a0l,d0w,d1w,d2w,d3w,d4w)"    },
  77.   { LIBClosestColour,   "ClosestColour(d0l,a0l)"               },
  78.   { LIBConvertHSVToRGB, "ConvertHSVToRGB(a0l)"                 },
  79.   { LIBConvertRGBToHSV, "ConvertRGBToHSV(d0l,a0l)"             },
  80.   { LIBCopyPalette,     "CopyPalette(a0l,a1l,d0l,d1l,d2l)"     },
  81.   { LIBDarkenArea,      "DarkenArea(a0l,d0w,d1w,d2w,d3w,d4w)"  },
  82.   { LIBLightenArea,     "LightenArea(a0l,d0w,d1w,d2w,d3w,d4w)" },
  83.   { LIBRemapBitmap,     "RemapBitmap(a0l,a1l,d0w)"             },
  84.   { LIBDarkenPixel,     "DarkenPixel(a0l,d0w,d1w,d2w)"         },
  85.   { LIBLightenPixel,    "LightenPixel(a0l,d0w,d1w,d2w)"        },
  86.   { LIBCalcBrightness,  "CalcBrightness(d0l)"                  },
  87.   { NULL, NULL }
  88. };
  89.  
  90. /************************************************************************************
  91. ** Command: Init()
  92. ** Short:   Called when our module is being loaded for the first time.
  93. */
  94.  
  95. LIBFUNC LONG CMDInit(mreg(__a0) LONG argModule,
  96.                   mreg(__a1) LONG argDPKBase,
  97.                   mreg(__a2) LONG argGVBase,
  98.                   mreg(__d0) LONG argDPKVersion,
  99.                   mreg(__d1) LONG argDPKRevision)
  100. {
  101.   WORD error = ERR_FAILED;
  102.  
  103.   DPKBase    = (APTR)argDPKBase;
  104.   GVBase     = (struct GVBase *)argGVBase;
  105.   Public     = ((struct Module *)argModule)->Public;
  106.   BlitterMod = NULL;
  107.  
  108.   if ((argDPKVersion < 0) OR ((argDPKVersion IS 0) AND (argDPKRevision < 0))) {
  109.      DPrintF("!Colours:","The colours module requires V%d.%d of the dpkernel library.",DPKVersion,DPKRevision);
  110.      return(ERR_FAILED);
  111.   }
  112.   else {
  113.      if (BlitterMod = Get(ID_MODULE|GET_NOTRACK)) {
  114.         BlitterMod->Number = MOD_BLITTER;
  115.         if (Init(BlitterMod,NULL)) {
  116.            BLTBase = BlitterMod->ModBase;
  117.            error = ERR_OK;
  118.         }
  119.      }
  120.   }
  121.  
  122. exit:
  123.   if (error) FreeModule();
  124.   return(error);
  125. }
  126.  
  127. /************************************************************************************
  128. ** Command: Open()
  129. ** Short:   Called when our module is being opened, i.e. Init(Module).
  130. */
  131.  
  132. LIBFUNC LONG CMDOpen(mreg(__a0) struct Module *Module)
  133. {
  134.   Module->FunctionList = JumpTableV1;
  135.   Public->OpenCount++;
  136.   return(ERR_OK);
  137. }
  138.  
  139. /************************************************************************************
  140. ** Command: Expunge()
  141. ** Short:   Called on expunge - if no program has us opened and no objects are
  142. **          in the system, then we can give permission to have us shut us down.
  143. */
  144.  
  145. LIBFUNC LONG CMDExpunge(void)
  146. {
  147.   if (Public) {
  148.      if (Public->OpenCount IS NULL) {
  149.         FreeModule();
  150.         return(ERR_OK); /* Okay to expunge */
  151.      }
  152.   }
  153.   else DPrintF("!Colours:","I have no public base reference.");
  154.  
  155.   return(ERR_FAILED); /* Do not expunge */
  156. }
  157.  
  158. /************************************************************************************
  159. ** Command: Close()
  160. ** Short:   Called whenever someone is closing a link to our module.
  161. */
  162.  
  163. LIBFUNC void CMDClose(mreg(__a0) struct Module *Module)
  164. {
  165.   Public->OpenCount--;
  166. }
  167.  
  168. /***********************************************************************************/
  169.  
  170. void FreeModule(void)
  171. {
  172.   if (BlitterMod) { Free(BlitterMod); BlitterMod = NULL; }
  173. }
  174.  
  175. /************************************************************************************
  176. ** Function: BlurArea()
  177. ** Short:    Blurs an area of a Bitmap.
  178. ** Synopsis: void BlurArea(*Bitmap [a0], WORD X [d0], WORD Y [d1],
  179. **             WORD Width [d2], WORD Height [d3], WORD Setting [d4])
  180. **
  181. ** The Setting argument alters how heavy the blurring is.
  182. */
  183.  
  184. LIBFUNC void LIBBlurArea(mreg(__a0) struct Bitmap *Bitmap, mreg(__d0) WORD XStart,
  185.                       mreg(__d1) WORD YStart, mreg(__d2) WORD Width,
  186.                       mreg(__d3) WORD Height, mreg(__d4) WORD Setting)
  187. {
  188.   WORD x, y;
  189.   LONG colour;
  190.   LONG R1,R2,R3,R4;
  191.   WORD Red, Green, Blue;
  192.  
  193.   if (Setting < 1) return;
  194.   if ((Height < 1) OR (Width < 1)) return;
  195.  
  196.   if (Bitmap) {
  197.      for (y = YStart; y < (YStart + Height); y++) {
  198.         for (x = XStart; x < (XStart + Width); x++) {
  199.            if ((R1 = ReadRGBPixel(Bitmap,x,y-1)) < 0) R1 = NULL;
  200.            if ((R2 = ReadRGBPixel(Bitmap,x,y+1)) < 0) R2 = NULL;
  201.            if ((R3 = ReadRGBPixel(Bitmap,x-1,y)) < 0) R3 = NULL;
  202.            if ((R4 = ReadRGBPixel(Bitmap,x+1,y)) < 0) R4 = NULL;
  203.  
  204.            /* Calculate the averages */
  205.  
  206.            Red    = ((R1>>16) + (R2>>16) + (R3>>16) + (R4>>16))/4;
  207.            Green  = ((R1>>8 & 0xff) + (R2>>8 & 0xff) + (R3>>8 & 0xff) + (R4>>8 & 0xff))/4;
  208.            Blue   = ((R1 & 0xff) + (R2 & 0xff) + (R3 & 0xff) + (R4 & 0xff))/4;
  209.            colour = (Red<<16)|(Green<<8)|(Blue);
  210.            DrawRGBPixel(Bitmap,x,y,colour);
  211.         }
  212.      }
  213.   }
  214.   else ErrCode(ERR_ARGS);
  215. }
  216.  
  217. /************************************************************************************
  218. ** Function: ClosestColour()
  219. ** Synopsis: LONG ClosestColour(LONG RGB, LONG *Palette)
  220. **
  221. ** Returns the colour number in the palette that best matches the given RGB colour.
  222. */
  223.  
  224. LIBFUNC LONG LIBClosestColour(mreg(__d0) LONG RGB,
  225.                            mreg(__a0) struct RGBPalette *Palette)
  226. {
  227.   WORD Red, Green, Blue, SrcRed, SrcGreen, SrcBlue, i;
  228.   LONG BestMatch = 0x7fffffff, Match, BestColour = NULL;
  229.  
  230.   #define HIQUALITY TRUE  /* Affects the speed of the routine - should be in GMSPrefs */
  231.  
  232.   #ifdef MISSION_CRITICAL
  233.   if (Palette->ID != PALETTE_ARRAY) return(NULL);
  234.   if (Palette->AmtColours <= 0)     return(NULL);
  235.   #endif
  236.  
  237.   SrcRed   = (RGB & 0x00ff0000)>>16;
  238.   SrcGreen = (RGB & 0x0000ff00)>>8;
  239.   SrcBlue  = (RGB & 0x000000ff);
  240.  
  241.   for (i=0; i < Palette->AmtColours; i++) {
  242.  
  243.    #ifndef HIQUALITY
  244.  
  245.      /* Average quality but fast routine */
  246.  
  247.      Red = SrcRed - (WORD)(Palette->Col[i].Red);
  248.      if (Red < 0) Red = -Red;
  249.  
  250.      Green = SrcGreen - (WORD)(Palette->Col[i].Green);
  251.      if (Green < 0) Green = -Green;
  252.  
  253.      Blue = SrcBlue - (WORD)(Palette->Col[i].Blue);
  254.      if (Blue < 0) Blue = -Blue;
  255.  
  256.      Match = Red + Green + Blue;
  257.  
  258.    #else
  259.  
  260.      /* Good quality but slower routine */
  261.  
  262.      Red   = SrcRed - (WORD)(Palette->Col[i].Red);
  263.      Green = SrcGreen - (WORD)(Palette->Col[i].Green);
  264.      Blue  = SrcBlue - (WORD)(Palette->Col[i].Blue);
  265.      Match = (Red * Red) + (Green * Green) + (Blue * Blue);
  266.  
  267.    #endif
  268.  
  269.      if (Match < BestMatch) {
  270.         BestMatch = Match;
  271.         BestColour = i;
  272.      }
  273.   }
  274.  
  275.   return(BestColour);
  276. }
  277.  
  278. /************************************************************************************
  279. ** Function: LONG Brightness(LONG RGB)
  280. ** Short:    Calculates the brightness of a colour, on a scale of 0 - 255.
  281. **
  282. ** This is the original floating point based formula:
  283. **
  284. **   ret = (0.239 * rgb.r) + (0.686 * rgb.g) + (0.075 * rgb.b));
  285. */
  286.  
  287. LIBFUNC LONG LIBCalcBrightness(mreg(__d0) LONG RGB)
  288. {
  289.   WORD Red   = (WORD)((RGB>>16) & 0x0000ff);
  290.   WORD Green = (WORD)((RGB>>8) & 0x0000ff);
  291.   WORD Blue  = (WORD)(RGB & 0x0000ff);
  292.  
  293.   return(((239 * Red) + (686 * Green) + (75 * Blue))/1000);
  294. }
  295.  
  296. /************************************************************************************
  297. ** Function: ConvertHSVToRGB()
  298. ** Synopsis: LONG ConvertHSVToRGB(struct HSV *HSV [a0])
  299. */
  300.  
  301. LIBFUNC LONG LIBConvertHSVToRGB(mreg(__a0) struct HSV *HSV)
  302. {
  303.  
  304.   /* Put code in here */
  305.  
  306.   return(NULL);
  307. }
  308.  
  309. /************************************************************************************
  310. ** Function: ConvertRGBToHSV()
  311. ** Synopsis: LONG ConvertRGBToHSV(LONG RGB)
  312. **
  313. ** Hue is between 0 and 360.
  314. ** Value is between 0 and 100.
  315. ** Saturation is between 0 and 100.
  316. */
  317.  
  318. LIBFUNC void LIBConvertRGBToHSV(mreg(__d0) LONG rgb, mreg(__a0) struct HSV *HSV)
  319. {
  320.    WORD delta;
  321.    WORD max, min;
  322.    WORD Red   = (WORD)((rgb>>16) & 0x00ff);
  323.    WORD Green = (WORD)((rgb>>8) & 0x00ff);
  324.    WORD Blue  = (WORD)(rgb & 0x00ff);
  325.  
  326.    max = Blue;
  327.    if (Green > max) max = Green;
  328.    if (Red > max)   max = Red;
  329.  
  330.    min = Blue;
  331.    if (Green < min) min = Green;
  332.    if (Red < min)   min = Red;
  333.  
  334.    /*** Calculate Value ***/
  335.  
  336.    HSV->Val = (max * 100)/255;
  337.  
  338.    /* Calculate Saturation.  Note that if the Saturation is
  339.    ** NULL then the Hue is also driven to NULL.
  340.    */
  341.  
  342.    if (max > 0) {
  343.       HSV->Sat = ((max-min)*100)/max;
  344.       if (HSV->Sat IS NULL) {
  345.          HSV->Hue = NULL;
  346.          return;
  347.       }
  348.    }
  349.    else {
  350.       HSV->Sat = NULL;
  351.       HSV->Hue = NULL;
  352.       return;
  353.    }
  354.  
  355.    /* Note:  The '<<8' is to get rid of the floating point numbers and
  356.    ** keep the calculations integer based.  This causes us to be
  357.    ** slightly innacurate (at most by 1) but we could improve this.
  358.    */
  359.  
  360.    delta = max - min;
  361.    if (max IS Red) {
  362.       HSV->Hue = ((((Green - Blue)<<8)/delta)*60)>>8;
  363.    }
  364.    else if (max IS Green) {
  365.       HSV->Hue = (((2<<8)+((Blue - Red)<<8)/delta)*60)>>8;
  366.    }
  367.    else {
  368.       HSV->Hue = (((4<<8)+((Red - Green)<<8)/delta)*60)>>8;
  369.    }
  370.  
  371.    if (HSV->Hue < 0) {
  372.       HSV->Hue += 360;
  373.    }
  374. }
  375.  
  376. /************************************************************************************
  377. ** Function: CopyPalette()
  378. ** Synopsis: LONG CopyPalette(LONG *SrcPalette [a0], LONG *DestPalette [a1],
  379. **             LONG ColStart [d0], LONG AmtColors [d1], LONG DestCol [d2])
  380. */
  381.  
  382. LIBFUNC LONG LIBCopyPalette(mreg(__a0) LONG argSrcPalette,
  383.                             mreg(__a1) LONG argDestPalette, mreg(__d0) LONG ColStart,
  384.                             mreg(__d1) LONG AmtColours, mreg(__d2) LONG DestCol)
  385. {
  386.   LONG *SrcPalette  = (LONG *)argSrcPalette;
  387.   LONG *DestPalette = (LONG *)argDestPalette;
  388.  
  389.   if ((SrcPalette IS NULL) OR (DestPalette IS NULL)) {
  390.      DPrintF("!CopyPalette:","Incorrect arguments.");
  391.      return(ERR_ARGS);
  392.   }
  393.  
  394.   if (AmtColours > (DestPalette[1] - DestCol)) {
  395.      DPrintF("!CopyPalette:","Cannot copy - range too large.");
  396.      return(ERR_FAILED);
  397.   }
  398.  
  399.   DestCol  += 2;
  400.   ColStart += 2;
  401.   while (AmtColours) {
  402.      DestPalette[DestCol++] = SrcPalette[ColStart++];
  403.      AmtColours--;
  404.   }
  405.  
  406.   return(ERR_OK);
  407. }
  408.  
  409. /************************************************************************************
  410. ** Function: DarkenArea()
  411. ** Synopsis: void DarkenArea(*Bitmap [a0], WORD StartX [d0], WORD StartY [d1],
  412. **             WORD EndX [d2], WORD EndY [d3], WORD Percent [d4])
  413. **
  414. ** This function is used to darken a rectangular area on a Bitmap.  The percentage
  415. ** range is from light to dark, so 5% will give you a lightly shaded area, while 95%
  416. ** will give an extremely dark area.
  417. */
  418.  
  419. LIBFUNC void LIBDarkenArea(mreg(__a0) struct Bitmap *Bitmap, mreg(__d0) WORD X,
  420.                            mreg(__d1) WORD Y,     mreg(__d2) WORD Height,
  421.                            mreg(__d3) WORD Width, mreg(__d4) WORD Percent)
  422. {
  423.   WORD CurrentX, Red, Green, Blue;
  424.   LONG Colour;
  425.   WORD Value;
  426.  
  427.   if ((Bitmap IS NULL) OR (Percent < 0) OR (Percent > 100) OR (Bitmap->Head.ID != ID_BITMAP)) {
  428.      DPrintF("!DarkenArea()","Incorrect arguments.");
  429.      return;
  430.   }
  431.  
  432.   /*** Clip the width and height ***/
  433.  
  434.   if (X < 0) { Width  += X; X = 0; }
  435.   if (Y < 0) { Height += Y; Y = 0; }
  436.  
  437.   if ((X + Width) >= Bitmap->Width) {
  438.      Width = Bitmap->Width - X;
  439.   }
  440.  
  441.   if ((Y + Height) >= Bitmap->Height) {
  442.      Height = Bitmap->Height - Y;
  443.   }
  444.  
  445.   if ((Height < 1) OR (Width < 1)) return;
  446.  
  447.   Width += X;
  448.  
  449.   Value = ((-Percent+100)<<8)/100; /* Value is between 0 and 256 inclusive */
  450.  
  451.   while (Height > 0) {
  452.      CurrentX = X;
  453.      while (CurrentX < Width) {
  454.         Colour = ReadRGBPixel(Bitmap,CurrentX,Y);
  455.         Red    = (((Colour>>16) & 0x00ff) * Value)>>8;
  456.         Green  = (((Colour>>8) & 0x00ff)  * Value)>>8;
  457.         Blue   = ((Colour & 0x00ff)       * Value)>>8;
  458.         DrawUCRGBPixel(Bitmap,CurrentX,Y,(Red<<16)|(Green<<8)|(Blue));
  459.         CurrentX++;
  460.      }
  461.      Y++;
  462.      Height--;
  463.   }
  464. }
  465.  
  466. /************************************************************************************
  467. ** Function: LightenArea()
  468. ** Synopsis: void LightenArea(*Bitmap [a0], WORD X [d0], WORD Y [d1],
  469. **             WORD Width [d2], WORD Height [d3], WORD Percent [d4])
  470. **
  471. ** This function is used to lighten a rectangular area on a Bitmap.  The higher the
  472. ** percentage, the brighter the area will be.
  473. */
  474.  
  475. LIBFUNC void LIBLightenArea(mreg(__a0) struct Bitmap *Bitmap, mreg(__d0) WORD X,
  476.                             mreg(__d1) WORD Y,      mreg(__d2) WORD Width,
  477.                             mreg(__d3) WORD Height, mreg(__d4) WORD Percent)
  478. {
  479.   WORD CurrentX, Red, Green, Blue;
  480.   LONG Colour;
  481.   WORD Value;
  482.  
  483.   if ((Bitmap IS NULL) OR (Percent < 0) OR (Percent > 100) OR (Bitmap->Head.ID != ID_BITMAP)) {
  484.      DPrintF("!LightenArea()","Incorrect arguments.");
  485.      return;
  486.   }
  487.  
  488.   /*** Clip the width and height ***/
  489.  
  490.   if (X < 0) { Width  += X; X = 0; }
  491.   if (Y < 0) { Height += Y; Y = 0; }
  492.  
  493.   if ((X + Width) >= Bitmap->Width) {
  494.      Width = Bitmap->Width - X;
  495.   }
  496.  
  497.   if ((Y + Height) >= Bitmap->Height) {
  498.      Height = Bitmap->Height - Y;
  499.   }
  500.  
  501.   if ((Height < 1) OR (Width < 1)) return;
  502.  
  503.   Width += X;
  504.  
  505.   Value = (Percent<<8)/100; /* Value is between 0 and 256 inclusive */
  506.  
  507.   while (Height > 0) {
  508.      CurrentX = X;
  509.      while (CurrentX < Width) {
  510.         Colour = ReadRGBPixel(Bitmap,CurrentX,Y);
  511.         Red    = (Colour>>16) & 0x00ff;  Red   += ((255-Red)*Value)>>8;
  512.         Green  = (Colour>>8)  & 0x00ff;  Green += ((255-Green)*Value)>>8;
  513.         Blue   = (Colour)     & 0x00ff;  Blue  += ((255-Blue)*Value)>>8;
  514.         DrawUCRGBPixel(Bitmap,CurrentX,Y,(Red<<16)|(Green<<8)|(Blue));
  515.         CurrentX++;
  516.      }
  517.      Y++;
  518.      Height--;
  519.   }
  520. }
  521.  
  522. /************************************************************************************
  523. ** Function: DarkenPixel()
  524. ** Synopsis: void DarkenPixel(*Bitmap [a0], WORD X [d0], WORD Y [d1], WORD Percent [d2])
  525. ** Short:    Darkens a pixel by the specified value.
  526. */
  527.  
  528. LIBFUNC void LIBDarkenPixel(mreg(__a0) struct Bitmap *Bitmap, mreg(__d0) WORD X,
  529.                             mreg(__d1) WORD Y, mreg(__d2) WORD Percent)
  530. {
  531.   LONG Red, Green, Blue;
  532.   LONG Colour;
  533.   WORD Value;
  534.  
  535.   if (Bitmap IS NULL) return;
  536.   #ifdef MISSION_CRITICAL
  537.   if ((Percent < 0) OR (Percent > 100) OR (Bitmap->Head.ID != ID_BITMAP)) return;
  538.   #endif
  539.  
  540.   Value  = ((-Percent+100)<<8)/100; /* Value is between 0 and 256 inclusive */
  541.   Colour = ReadRGBPixel(Bitmap,X,Y);
  542.   Red    = (((BYTE)(Colour>>16) * Value)<<8) & 0x00ff0000;
  543.   Green  = ((BYTE)(Colour>>8) * Value) & 0x0000ff00;
  544.   Blue   = ((BYTE)Colour * Value)>>8;
  545.   DrawRGBPixel(Bitmap,X,Y,(Red)|(Green)|(Blue));
  546. }
  547.  
  548. /************************************************************************************
  549. ** Function: LightenPixel()
  550. ** Synopsis: void LightenPixel(*Bitmap [a0], WORD X [d0], WORD Y [d1], WORD Percent [d2])
  551. ** Short:    Lightens a pixel by the specified value.
  552. **
  553. */
  554.  
  555. LIBFUNC void LIBLightenPixel(mreg(__a0) struct Bitmap *Bitmap, mreg(__d0) WORD X,
  556.                              mreg(__d1) WORD Y, mreg(__d2) WORD Percent)
  557. {
  558.   WORD Red, Green, Blue;
  559.   LONG Colour;
  560.   WORD Value;
  561.  
  562.   if (Bitmap IS NULL) return;
  563.   #ifdef MISSION_CRITICAL
  564.   if ((Percent < 0) OR (Percent > 100) OR (Bitmap->Head.ID != ID_BITMAP)) return;
  565.   #endif
  566.  
  567.   Value  = (Percent<<8)/100; /* Value is between 0 and 256 inclusive */
  568.   Colour = ReadRGBPixel(Bitmap,X,Y);
  569.   Red    = (Colour>>16) & 0x00ff;  Red   += ((255-Red)*Value)>>8;
  570.   Green  = (Colour>>8)  & 0x00ff;  Green += ((255-Green)*Value)>>8;
  571.   Blue   = (Colour)     & 0x00ff;  Blue  += ((255-Blue)*Value)>>8;
  572.   DrawRGBPixel(Bitmap,X,Y,(Red<<16)|(Green<<8)|(Blue));
  573. }
  574.  
  575. /************************************************************************************
  576. ** Function: RemapBitmap()
  577. ** Synopsis: LONG RemapBitmap(*SrcBitmap [a0], *DestBitmap [a1],
  578. **             WORD Performance [d0])
  579. **
  580. ** You can use this function to remap the colours of a Bitmap to a new set of
  581. ** colour values.
  582. ** 
  583. ** INPUTS
  584. ** SrcBitmap
  585. **   The Bitmap that is acting as the source.
  586. **
  587. ** DestBitmap
  588. **   The Bitmap that will receive the remapped data.
  589. **
  590. ** Performance
  591. **   This is a performance rating from 0 - 100%.  If you specify 50% you will
  592. **   get a straight remap to the destination.  A setting of 100% would enable
  593. **   anti-aliasing and smoothing facilities, at a cost of being a lot slower.
  594. **
  595. ** RESULT
  596. ** Returns ERR_OK if successful.
  597. */
  598.  
  599. LIBFUNC LONG LIBRemapBitmap(mreg(__a0) LONG argSource, mreg(__a1) LONG argDest,
  600.                             mreg(__d0) WORD Performance)
  601. {
  602.   struct Bitmap *Src  = (struct Bitmap *)argSource;
  603.   struct Bitmap *Dest = (struct Bitmap *)argDest;
  604.   WORD MaxWidth, y, MaxHeight;
  605.  
  606.   DPrintF("RemapBitmap()","Source: $%x,  Dest: $%x", Src, Dest);
  607.  
  608.   /*** Validate arguments ***/
  609.  
  610.   if ((Src IS NULL) OR (Dest IS NULL) OR (Src IS Dest)) {
  611.      return(ErrCode(ERR_ARGS));
  612.   }
  613.  
  614.   /*** Get the maximum width and height ***/
  615.  
  616.   if (Src->Width < Dest->Width) {
  617.      MaxWidth = Src->Width;
  618.   }
  619.   else {
  620.      MaxWidth = Dest->Width;
  621.   }
  622.  
  623.   if (Src->Height < Dest->Height) {
  624.      MaxHeight = Src->Height;
  625.   }
  626.   else {
  627.      MaxHeight = Dest->Height;
  628.   }
  629.  
  630.   /*** Remapping process ***/
  631.  
  632.   for (y=0; y < MaxHeight; y++) {
  633.      CopyLine(Src,Dest,y,y,MaxWidth,1); /* Easy remap! */
  634.  
  635.      /*** Clear off any trailing pixels if DestWidth > SrcWidth ***/
  636.  
  637.      if (MaxWidth < Dest->Width) {
  638.         DrawLine(Dest,MaxWidth,y,Dest->Width-1,y,0,0xffffffff);
  639.      }
  640.   }
  641.  
  642.   /*** Clear off any trailing pixels from the bottom ***/
  643.  
  644.   if (Dest->Height > Src->Height) {
  645.      for (y=y; y < Dest->Height; y++) {
  646.         DrawLine(Dest,0,y,Dest->Width-1,y,0,0);
  647.      }
  648.   }
  649.  
  650.   return(ERR_OK);
  651. }
  652.  
  653.